﻿///
/// @file InstSelectorArm64.cpp
/// @brief 指令选择器-ARM64的实现
/// @author zenglj (zenglj@live.com)
/// @version 1.0
/// @date 2024-11-21
///
/// @copyright Copyright (c) 2024
///
/// @par 修改日志:
/// <table>
/// <tr><th>Date       <th>Version <th>Author  <th>Description
/// <tr><td>2024-11-21 <td>1.0     <td>zenglj  <td>新做
/// </table>
///
#include <cstdio>

#include "Common.h"
#include "ILocArm64.h"
#include "InstSelectorArm64.h"
#include "PlatformArm64.h"

#include "PointerType.h"
#include "RegVariable.h"
#include "Function.h"

#include "LabelInstruction.h"
#include "GotoInstruction.h"
#include "FuncCallInstruction.h"
#include "MoveInstruction.h"

#include "Instructions/GetElementPtrInstruction.h"
#include "Constant.h"

/// @brief 构造函数
/// @param _irCode 指令
/// @param _iloc ILoc
/// @param _func 函数
InstSelectorArm64::InstSelectorArm64(vector<Instruction *> & _irCode,
                                     ILocArm64 & _iloc,
                                     Function * _func,
                                     SimpleRegisterAllocator & allocator)
    : ir(_irCode), iloc(_iloc), func(_func), simpleRegisterAllocator(allocator)
{
    translator_handlers[IRInstOperator::IRINST_OP_ENTRY] = &InstSelectorArm64::translate_entry;
    translator_handlers[IRInstOperator::IRINST_OP_EXIT] = &InstSelectorArm64::translate_exit;

    translator_handlers[IRInstOperator::IRINST_OP_LABEL] = &InstSelectorArm64::translate_label;
    translator_handlers[IRInstOperator::IRINST_OP_GOTO] = &InstSelectorArm64::translate_goto;

    translator_handlers[IRInstOperator::IRINST_OP_ASSIGN] = &InstSelectorArm64::translate_assign;

    translator_handlers[IRInstOperator::IRINST_OP_ADD_I] = &InstSelectorArm64::translate_add_int32;
    translator_handlers[IRInstOperator::IRINST_OP_SUB_I] = &InstSelectorArm64::translate_sub_int32;
    translator_handlers[IRInstOperator::IRINST_OP_MUL_I] = &InstSelectorArm64::translate_mul_int32;

    translator_handlers[IRInstOperator::IRINST_OP_DIV_I] = &InstSelectorArm64::translate_div_int32;

    translator_handlers[IRInstOperator::IRINST_OP_MOD_I] = &InstSelectorArm64::translate_mod_int32;
    translator_handlers[IRInstOperator::IRINST_OP_LESS_I] = &InstSelectorArm64::translate_lt_int32;

    translator_handlers[IRInstOperator::IRINST_OP_GREATER_I] = &InstSelectorArm64::translate_gt_int32;
    translator_handlers[IRInstOperator::IRINST_OP_LESS_EQUAL_I] = &InstSelectorArm64::translate_le_int32;
    translator_handlers[IRInstOperator::IRINST_OP_GREATER_EQUAL_I] = &InstSelectorArm64::translate_ge_int32;
    translator_handlers[IRInstOperator::IRINST_OP_EQ_I] = &InstSelectorArm64::translate_eq_int32;
    translator_handlers[IRInstOperator::IRINST_OP_NEQ_I] = &InstSelectorArm64::translate_ne_int32;
    translator_handlers[IRInstOperator::IRINST_OP_LNOT_I] = &InstSelectorArm64::translate_not_int32;
    translator_handlers[IRInstOperator::IRINST_OP_LAND_I] = &InstSelectorArm64::translate_and_int32;
    translator_handlers[IRInstOperator::IRINST_OP_LOR_I] = &InstSelectorArm64::translate_or_int32;

    translator_handlers[IRInstOperator::IRINST_OP_FUNC_CALL] = &InstSelectorArm64::translate_call;
    translator_handlers[IRInstOperator::IRINST_OP_ARG] = &InstSelectorArm64::translate_arg;

    translator_handlers[IRInstOperator::IRINST_OP_UNARY_MINUS_I] = &InstSelectorArm64::translate_neg_int32;
    translator_handlers[IRInstOperator::IRINST_OP_UNARY_PLUS_I] = &InstSelectorArm64::translate_unary_plus_int32;
    translator_handlers[IRInstOperator::IRINST_OP_BRANCH] = &InstSelectorArm64::translate_branch;

    // Add handlers for array access, store, and load
    translator_handlers[IRInstOperator::IRINST_OP_ARRAY_ACCESS] = &InstSelectorArm64::translate_array_access;
    translator_handlers[IRInstOperator::IRINST_OP_STORE] = &InstSelectorArm64::translate_store;
    translator_handlers[IRInstOperator::IRINST_OP_LOAD] = &InstSelectorArm64::translate_load;
    translator_handlers[IRInstOperator::IRINST_OP_CAST] = &InstSelectorArm64::translate_cast;

    translator_handlers[IRInstOperator::IRINST_OP_ZEROSET] = &InstSelectorArm64::translate_zeroset;
}

///
/// @brief 析构函数
///
InstSelectorArm64::~InstSelectorArm64()
{}

/// @brief 指令选择执行
void InstSelectorArm64::run()
{
    for (auto inst: ir) {

        // 逐个指令进行翻译
        if (!inst->isDead()) {
            translate(inst);
        }
    }
}

/// @brief 指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate(Instruction * inst)
{
    // 操作符
    IRInstOperator op = inst->getOp();

    map<IRInstOperator, translate_handler>::const_iterator pIter;
    pIter = translator_handlers.find(op);
    if (pIter == translator_handlers.end()) {
        // 没有找到，则说明当前不支持
        printf("Translate: Operator(%d) not support", (int) op);
        return;
    }

    // 开启时输出IR指令作为注释
    if (showLinearIR) {
        outputIRInstruction(inst);
    }

    (this->*(pIter->second))(inst);
}

///
/// @brief 输出IR指令
///
void InstSelectorArm64::outputIRInstruction(Instruction * inst)
{
    std::string irStr;
    inst->toString(irStr);
    if (!irStr.empty()) {
        iloc.comment(irStr);
    }
}

/// @brief NOP翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_nop(Instruction * inst)
{
    (void) inst;
    iloc.nop();
}

/// @brief Label指令指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_label(Instruction * inst)
{
    Instanceof(labelInst, LabelInstruction *, inst);

    iloc.label(labelInst->getName());
}

/// @brief goto指令指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_goto(Instruction * inst)
{
    Instanceof(gotoInst, GotoInstruction *, inst);

    // 无条件跳转
    iloc.jump(gotoInst->getTarget()->getName());
}

static bool is_addsub_imm(int64_t val)
{
    return (val >= 0 && val < 4096) || (val >= 0 && (val & 0xfff000) == val && (val % 4096 == 0));
}

void InstSelectorArm64::translate_entry(Instruction * inst)
{
    auto & protectedRegNo = func->getProtectedReg();
    auto & protectedRegStr = func->getProtectedRegStr();
    bool first = true;
    for (auto regno: protectedRegNo) {
        if (first) {
            protectedRegStr = PlatformArm64::regName[regno];
            first = false;
        } else {
            protectedRegStr += "," + PlatformArm64::regName[regno];
        }
    }

    // 修复：重新计算栈帧大小，确保16字节对齐
    int funcCallArgCnt = func->getMaxFuncCallArgCnt() - 8;
    funcCallArgCnt = std::max(funcCallArgCnt, 0);

    // 实参空间：每个超出8个的参数占8字节，16字节对齐
    int arg_space = funcCallArgCnt * 8;
    if (arg_space % 16 != 0) {
        arg_space += 16 - (arg_space % 16);
    }

    // 局部变量空间：已经在stackAlloc中16字节对齐
    int local_space = func->getMaxDep();

    // 保护寄存器空间：16字节对齐
    int save_size = 0;
    if (protectedRegNo.size() >= 2) {
        save_size = protectedRegNo.size() * 8;
        if (save_size % 16 != 0) {
            save_size += 16 - (save_size % 16);
        }
    } else if (protectedRegNo.size() == 1) {
        save_size = 16; // 单个寄存器也要16字节对齐
    }

    // 总栈帧大小：确保16字节对齐
    int frame_size = local_space + arg_space + save_size;
    if (frame_size % 16 != 0) {
        frame_size += 16 - (frame_size % 16);
    }

    // 保存fp/lr并分配栈帧
    if (protectedRegNo.size() >= 2) {
        if (save_size < 65536) {
            iloc.inst("stp",
                      PlatformArm64::regName[protectedRegNo[0]],
                      PlatformArm64::regName[protectedRegNo[1]],
                      "[sp, #-" + iloc.toStr(save_size, false) + "]!");
        } else {
            // 大偏移量，需要先计算
            int tmp_reg = ARM64_TMP_REG_NO;
            iloc.load_imm(tmp_reg, -save_size);
            iloc.inst("stp",
                      PlatformArm64::regName[protectedRegNo[0]],
                      PlatformArm64::regName[protectedRegNo[1]],
                      "[sp, " + PlatformArm64::regName[tmp_reg] + "]!");
        }
    } else if (protectedRegNo.size() == 1) {
        if (save_size < 65536) {
            iloc.inst("str",
                      PlatformArm64::regName[protectedRegNo[0]],
                      "[sp, #-" + iloc.toStr(save_size, false) + "]!");
        } else {
            int tmp_reg = ARM64_TMP_REG_NO;
            iloc.load_imm(tmp_reg, -save_size);
            iloc.inst("str",
                      PlatformArm64::regName[protectedRegNo[0]],
                      "[sp, " + PlatformArm64::regName[tmp_reg] + "]!");
        }
    }

    // 分配剩余栈帧空间
    if (frame_size > save_size) {
        int remaining = frame_size - save_size;
        if (is_addsub_imm(remaining)) {
            iloc.inst("sub",
                      PlatformArm64::regName[ARM64_SP_REG_NO],
                      PlatformArm64::regName[ARM64_SP_REG_NO],
                      iloc.toStr(remaining, false));
        } else {
            int tmp_reg = ARM64_TMP_REG_NO;
            iloc.load_imm(tmp_reg, remaining);
            iloc.inst("sub",
                      PlatformArm64::regName[ARM64_SP_REG_NO],
                      PlatformArm64::regName[ARM64_SP_REG_NO],
                      PlatformArm64::regName[tmp_reg]);
        }
    }

    // 设置fp = sp + arg_space
    if (arg_space > 0) {
        if (is_addsub_imm(arg_space)) {
            iloc.inst("add",
                      PlatformArm64::regName[ARM64_FP_REG_NO],
                      PlatformArm64::regName[ARM64_SP_REG_NO],
                      iloc.toStr(arg_space, false));
        } else {
            int tmp_reg = ARM64_TMP_REG_NO;
            iloc.load_imm(tmp_reg, arg_space);
            iloc.inst("add",
                      PlatformArm64::regName[ARM64_FP_REG_NO],
                      PlatformArm64::regName[ARM64_SP_REG_NO],
                      PlatformArm64::regName[tmp_reg]);
        }
    } else {
        iloc.inst("mov", PlatformArm64::regName[ARM64_FP_REG_NO], PlatformArm64::regName[ARM64_SP_REG_NO]);
    }

    int paramsNum = inst->getOperandsNum();
    if (paramsNum) {
        for (int i = 0; i < paramsNum; ++i) {
            Value * arg = inst->getOperand(i);

            // 检查参数类型
            Type * argType = arg->getType();
            bool is_float = false;
            if (argType) {
                is_float = argType->isFloatType();
            } else {
                minic_log(LOG_WARNING, "Parameter has no type, assuming integer");
                is_float = false;
            }

            int32_t arg_regId = arg->getRegId();
            if (arg_regId != -1) {
                iloc.store_var(arg_regId, arg, ARM64_TMP_REG_NO, is_float);
            } else {
                int32_t temp_regno = simpleRegisterAllocator.Allocate(is_float);
                iloc.load_var(temp_regno, arg, is_float);
                iloc.store_var(temp_regno, arg, ARM64_TMP_REG_NO, is_float);
                simpleRegisterAllocator.free(temp_regno, is_float);
            }
        }
    }
}

void InstSelectorArm64::translate_exit(Instruction * inst)
{
    if (inst->getOperandsNum()) {
        Value * retVal = inst->getOperand(0);

        // 添加空指针检查
        if (!retVal) {
            minic_log(LOG_ERROR, "Null return value in exit instruction");
        } else {
            // 检查返回值类型
            Type * retType = retVal->getType();
            bool is_float = false;
            if (retType) {
                is_float = retType->isFloatType();
            } else {
                // 如果返回值没有类型信息，根据函数返回类型推断
                if (func && func->getReturnType()) {
                    is_float = func->getReturnType()->isFloatType();
                    minic_log(LOG_DEBUG,
                              "Return value has no type, using function return type: %s",
                              is_float ? "float" : "int");
                } else {
                    minic_log(LOG_WARNING, "Return value and function both have no type, assuming integer");
                    is_float = false;
                }
            }

            iloc.load_var(0, retVal, is_float);
        }
    }

    auto & protectedRegNo = func->getProtectedReg();

    int funcCallArgCnt = func->getMaxFuncCallArgCnt() - 8;
    funcCallArgCnt = std::max(funcCallArgCnt, 0);

    // 重新计算栈帧大小（与entry保持一致）
    int arg_space = funcCallArgCnt * 8;
    if (arg_space % 16 != 0) {
        arg_space += 16 - (arg_space % 16);
    }

    int local_space = func->getMaxDep();

    int save_size = 0;
    if (protectedRegNo.size() >= 2) {
        save_size = protectedRegNo.size() * 8;
        if (save_size % 16 != 0) {
            save_size += 16 - (save_size % 16);
        }
    } else if (protectedRegNo.size() == 1) {
        save_size = 16;
    }

    int frame_size = local_space + arg_space + save_size;
    if (frame_size % 16 != 0) {
        frame_size += 16 - (frame_size % 16);
    }

    // 恢复栈指针
    if (frame_size > save_size) {
        int restore_amount = frame_size - save_size;
        if (is_addsub_imm(restore_amount)) {
            iloc.inst("add",
                      PlatformArm64::regName[ARM64_SP_REG_NO],
                      PlatformArm64::regName[ARM64_SP_REG_NO],
                      iloc.toStr(restore_amount, false));
        } else {
            int tmp_reg = ARM64_TMP_REG_NO;
            iloc.load_imm(tmp_reg, restore_amount);
            iloc.inst("add",
                      PlatformArm64::regName[ARM64_SP_REG_NO],
                      PlatformArm64::regName[ARM64_SP_REG_NO],
                      PlatformArm64::regName[tmp_reg]);
        }
    }

    // 恢复fp = sp + arg_space
    if (arg_space > 0) {
        if (is_addsub_imm(arg_space)) {
            iloc.inst("add",
                      PlatformArm64::regName[ARM64_FP_REG_NO],
                      PlatformArm64::regName[ARM64_SP_REG_NO],
                      iloc.toStr(arg_space, false));
        } else {
            int tmp_reg = ARM64_TMP_REG_NO;
            iloc.load_imm(tmp_reg, arg_space);
            iloc.inst("add",
                      PlatformArm64::regName[ARM64_FP_REG_NO],
                      PlatformArm64::regName[ARM64_SP_REG_NO],
                      PlatformArm64::regName[tmp_reg]);
        }
    } else {
        iloc.inst("mov", PlatformArm64::regName[ARM64_FP_REG_NO], PlatformArm64::regName[ARM64_SP_REG_NO]);
    }

    // 恢复fp/lr并回收栈帧
    if (protectedRegNo.size() >= 2) {
        if (is_addsub_imm(save_size)) {
            iloc.inst("ldp",
                      PlatformArm64::regName[protectedRegNo[0]],
                      PlatformArm64::regName[protectedRegNo[1]],
                      "[sp], #" + iloc.toStr(save_size, false));
        } else {
            int tmp_reg = ARM64_TMP_REG_NO;
            iloc.load_imm(tmp_reg, save_size);
            iloc.inst("ldp",
                      PlatformArm64::regName[protectedRegNo[0]],
                      PlatformArm64::regName[protectedRegNo[1]],
                      "[sp], " + PlatformArm64::regName[tmp_reg]);
        }
    } else if (protectedRegNo.size() == 1) {
        if (is_addsub_imm(save_size)) {
            iloc.inst("ldr", PlatformArm64::regName[protectedRegNo[0]], "[sp], #" + iloc.toStr(save_size, false));
        } else {
            int tmp_reg = ARM64_TMP_REG_NO;
            iloc.load_imm(tmp_reg, save_size);
            iloc.inst("ldr", PlatformArm64::regName[protectedRegNo[0]], "[sp], " + PlatformArm64::regName[tmp_reg]);
        }
    }

    iloc.inst("ret", "");
}

/// @brief 赋值指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_assign(Instruction * inst)
{
    Value * result = inst->getOperand(0); // 目标操作数
    Value * arg1 = inst->getOperand(1);   // 源操作数

    // 添加空指针检查
    if (!result || !arg1) {
        minic_log(LOG_ERROR, "Null operand in assign instruction");
        return;
    }

    // 对于赋值指令，应该以源操作数的类型为准，因为目标操作数可能还没有类型信息
    Type * arg1Type = arg1->getType();
    // if (!arg1Type) {
    //     minic_log(LOG_ERROR, "Null type for source operand in assign");
    //     return; // 提前返回，避免了段错误(很关键，如果arg1Type为nullptr，则下面的isFloat会出错)
    // }
    bool is_float = false;

    if (arg1Type) {
        is_float = arg1Type->isFloatType();
    } else {
        // 提供备用逻辑而不是直接返回
        // minic_log(LOG_WARNING, "Source operand has no type, trying to infer from context");

        // 尝试从目标操作数推断
        Type * resultType = result->getType();
        if (resultType) {
            is_float = resultType->isFloatType();
        } else {
            // 最后的默认假设
            is_float = false;
            // minic_log(LOG_DEBUG, "Assuming integer type for assign instruction");
        }
    }

    // 使用源操作数的类型来判断是否为浮点类型
    // bool is_float = arg1Type->isFloatType();

    // // 检查目标操作数的类型（如果有的话）- 仅用于调试
    // Type * resultType = result->getType();
    // if (resultType) {
    //     bool result_is_float = resultType->isFloatType();
    //     if (result_is_float != is_float) {
    //         minic_log(LOG_DEBUG, "Type mismatch in assign: source=%s, target=%s",
    //                  is_float ? "float" : "int",
    //                  result_is_float ? "float" : "int");
    //     }
    // } else {
    //     minic_log(LOG_DEBUG, "Target operand has no type, using source type: %s",
    //              is_float ? "float" : "int");
    // }

    int32_t arg1_regId = arg1->getRegId();
    int32_t result_regId = result->getRegId();

    if (arg1_regId != -1) {
        // 寄存器 => 内存
        // 寄存器 => 寄存器
        iloc.store_var(arg1_regId, result, ARM64_TMP_REG_NO, is_float);
    } else if (result_regId != -1) {
        // 内存变量 => 寄存器
        iloc.load_var(result_regId, arg1, is_float);
    } else {
        // 内存变量 => 内存变量
        int32_t temp_regno = simpleRegisterAllocator.Allocate(is_float);

        // arg1 -> temp_reg
        iloc.load_var(temp_regno, arg1, is_float);

        // temp_reg -> result
        iloc.store_var(temp_regno, result, ARM64_TMP_REG_NO, is_float);

        simpleRegisterAllocator.free(temp_regno, is_float);
    }
}

/// @brief 二元操作指令翻译成ARM64汇编
/// @param inst IR指令
/// @param operator_name 操作码
/// @param rs_reg_no 结果寄存器号
/// @param op1_reg_no 源操作数1寄存器号
/// @param op2_reg_no 源操作数2寄存器号
void InstSelectorArm64::translate_two_operator(Instruction * inst, string operator_name)
{
    Value * result = inst;
    Value * arg1 = inst->getOperand(0);
    Value * arg2 = inst->getOperand(1);

    // 添加空指针检查
    if (!result || !arg1 || !arg2) {
        minic_log(LOG_ERROR, "Null operand in two operator instruction");
        return;
    }

    // 对于二元操作，通常操作数1和操作数2的类型应该一致
    // 先检查操作数的类型
    Type * arg1Type = arg1->getType();
    Type * arg2Type = arg2->getType();

    bool is_float = false;
    if (arg1Type) {
        is_float = arg1Type->isFloatType();
    } else if (arg2Type) {
        is_float = arg2Type->isFloatType();
    } else {
        minic_log(LOG_WARNING, "Both operands have no type, assuming integer");
        is_float = false;
    }

    // 检查结果类型（如果有的话）
    Type * resultType = result->getType();
    if (resultType) {
        bool result_is_float = resultType->isFloatType();
        if (result_is_float != is_float) {
            minic_log(LOG_DEBUG, "Result type differs from operand types, using operand type");
        }
    }

    int32_t arg1_reg_no = arg1->getRegId();
    int32_t arg2_reg_no = arg2->getRegId();
    int32_t result_reg_no = result->getRegId();

    // 看arg1是否是寄存器，若是则寄存器寻址，否则要load变量到寄存器中
    if (arg1_reg_no == -1) {
        arg1_reg_no = simpleRegisterAllocator.Allocate(is_float, arg1);
        iloc.load_var(arg1_reg_no, arg1, is_float);
    }
    if (arg2_reg_no == -1) {
        arg2_reg_no = simpleRegisterAllocator.Allocate(is_float, arg2);
        iloc.load_var(arg2_reg_no, arg2, is_float);
    }
    if (result_reg_no == -1) {
        result_reg_no = simpleRegisterAllocator.Allocate(is_float, result);
    } else {
        simpleRegisterAllocator.AllocateReg(result_reg_no, is_float);
    }

    // 根据类型选择正确的指令和寄存器名
    string actual_op = operator_name;
    if (is_float) {
        // 浮点运算需要使用浮点指令
        if (operator_name == "add")
            actual_op = "fadd";
        else if (operator_name == "sub")
            actual_op = "fsub";
        else if (operator_name == "mul")
            actual_op = "fmul";
        else if (operator_name == "sdiv")
            actual_op = "fdiv";

        iloc.inst(actual_op,
                  PlatformArm64::regNameS[result_reg_no],
                  PlatformArm64::regNameS[arg1_reg_no],
                  PlatformArm64::regNameS[arg2_reg_no]);
    } else {
        iloc.inst(actual_op,
                  PlatformArm64::regName[result_reg_no],
                  PlatformArm64::regName[arg1_reg_no],
                  PlatformArm64::regName[arg2_reg_no]);
    }

    iloc.store_var(result_reg_no, result, ARM64_TMP_REG_NO, is_float);

    // 释放寄存器
    simpleRegisterAllocator.free(arg1, is_float);
    simpleRegisterAllocator.free(arg2, is_float);
    if (result_reg_no == -1) {
        simpleRegisterAllocator.free(result, is_float);
    }
}

/// @brief 整数加法指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_add_int32(Instruction * inst)
{
    translate_two_operator(inst, "add");
}

/// @brief 整数减法指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_sub_int32(Instruction * inst)
{
    translate_two_operator(inst, "sub");
}

/// @brief 整数乘法指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_mul_int32(Instruction * inst)
{
    translate_two_operator(inst, "mul");
}

/// @brief 整数除法指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_div_int32(Instruction * inst)
{
    translate_two_operator(inst, "sdiv");
}

/// @brief 整数取余指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_mod_int32(Instruction * inst)
{
    Value * result = inst;
    Value * arg1 = inst->getOperand(0);
    Value * arg2 = inst->getOperand(1);

    int32_t arg1_reg_no = arg1->getRegId();
    int32_t arg2_reg_no = arg2->getRegId();
    int32_t result_reg_no = inst->getRegId();

    // 分配寄存器 - 整型
    int32_t reg_a = (arg1_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(arg1) : arg1_reg_no;
    if (arg1_reg_no == -1)
        iloc.load_var(reg_a, arg1, false);

    int32_t reg_b = (arg2_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(arg2) : arg2_reg_no;
    if (arg2_reg_no == -1)
        iloc.load_var(reg_b, arg2, false);

    // 商寄存器
    int32_t reg_quot = simpleRegisterAllocator.AllocateInt();
    // sdiv reg_quot, reg_a, reg_b
    iloc.inst("sdiv", PlatformArm64::regName[reg_quot], PlatformArm64::regName[reg_a], PlatformArm64::regName[reg_b]);

    // 结果寄存器
    int32_t reg_rem = (result_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(result) : result_reg_no;
    // msub reg_rem, reg_quot, reg_b, reg_a  // reg_rem = reg_a - reg_quot * reg_b
    iloc.inst("msub",
              PlatformArm64::regName[reg_rem],
              PlatformArm64::regName[reg_quot],
              PlatformArm64::regName[reg_b] + ", " + PlatformArm64::regName[reg_a]);

    // 总是将结果写回内存，确保不会丢失
    iloc.store_var(reg_rem, result, ARM64_TMP_REG_NO, false);

    // 释放寄存器
    simpleRegisterAllocator.freeInt(arg1);
    simpleRegisterAllocator.freeInt(arg2);
    simpleRegisterAllocator.freeInt(reg_quot);
    if (result_reg_no == -1) {
        simpleRegisterAllocator.freeInt(reg_rem);
    }
}

/// @brief 小于指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_lt_int32(Instruction * inst)
{
    Value * result = inst;
    Value * arg1 = inst->getOperand(0);
    Value * arg2 = inst->getOperand(1);

    int32_t arg1_reg_no = arg1->getRegId();
    int32_t arg2_reg_no = arg2->getRegId();
    int32_t result_reg_no = inst->getRegId();

    int32_t reg_a = (arg1_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(arg1) : arg1_reg_no;
    if (arg1_reg_no == -1)
        iloc.load_var(reg_a, arg1, false);

    int32_t reg_b = (arg2_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(arg2) : arg2_reg_no;
    if (arg2_reg_no == -1)
        iloc.load_var(reg_b, arg2, false);

    int32_t reg_res = (result_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(result) : result_reg_no;

    // cmp reg_a, reg_b
    iloc.inst("cmp", PlatformArm64::regName[reg_a], PlatformArm64::regName[reg_b]);
    // cset reg_res, lt
    iloc.inst("cset", PlatformArm64::regName[reg_res], "lt");

    // 总是将结果写回内存，确保不会丢失
    iloc.store_var(reg_res, result, ARM64_TMP_REG_NO, false);

    simpleRegisterAllocator.freeInt(arg1);
    simpleRegisterAllocator.freeInt(arg2);
    if (result_reg_no == -1) {
        simpleRegisterAllocator.freeInt(reg_res);
    }
}

/// @brief 小于等于指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_le_int32(Instruction * inst)
{
    Value * result = inst;
    Value * arg1 = inst->getOperand(0);
    Value * arg2 = inst->getOperand(1);

    int32_t arg1_reg_no = arg1->getRegId();
    int32_t arg2_reg_no = arg2->getRegId();
    int32_t result_reg_no = inst->getRegId();

    int32_t reg_a = (arg1_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(arg1) : arg1_reg_no;
    if (arg1_reg_no == -1)
        iloc.load_var(reg_a, arg1, false);

    int32_t reg_b = (arg2_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(arg2) : arg2_reg_no;
    if (arg2_reg_no == -1)
        iloc.load_var(reg_b, arg2, false);

    int32_t reg_res = (result_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(result) : result_reg_no;

    // cmp reg_a, reg_b
    iloc.inst("cmp", PlatformArm64::regName[reg_a], PlatformArm64::regName[reg_b]);
    // cset reg_res, le
    iloc.inst("cset", PlatformArm64::regName[reg_res], "le");

    // 总是将结果写回内存，确保不会丢失
    iloc.store_var(reg_res, result, ARM64_TMP_REG_NO, false);

    simpleRegisterAllocator.freeInt(arg1);
    simpleRegisterAllocator.freeInt(arg2);
    if (result_reg_no == -1) {
        simpleRegisterAllocator.freeInt(reg_res);
    }
}

/// @brief 大于指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_gt_int32(Instruction * inst)
{
    Value * result = inst;
    Value * arg1 = inst->getOperand(0);
    Value * arg2 = inst->getOperand(1);

    int32_t arg1_reg_no = arg1->getRegId();
    int32_t arg2_reg_no = arg2->getRegId();
    int32_t result_reg_no = inst->getRegId();

    int32_t reg_a = (arg1_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(arg1) : arg1_reg_no;
    if (arg1_reg_no == -1)
        iloc.load_var(reg_a, arg1, false);

    int32_t reg_b = (arg2_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(arg2) : arg2_reg_no;
    if (arg2_reg_no == -1)
        iloc.load_var(reg_b, arg2, false);

    int32_t reg_res = (result_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(result) : result_reg_no;

    // cmp reg_a, reg_b
    iloc.inst("cmp", PlatformArm64::regName[reg_a], PlatformArm64::regName[reg_b]);
    // cset reg_res, gt
    iloc.inst("cset", PlatformArm64::regName[reg_res], "gt");

    // 总是将结果写回内存，确保不会丢失
    iloc.store_var(reg_res, result, ARM64_TMP_REG_NO, false);

    simpleRegisterAllocator.freeInt(arg1);
    simpleRegisterAllocator.freeInt(arg2);
    if (result_reg_no == -1) {
        simpleRegisterAllocator.freeInt(reg_res);
    }
}

/// @brief 大于等于指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_ge_int32(Instruction * inst)
{
    Value * result = inst;
    Value * arg1 = inst->getOperand(0);
    Value * arg2 = inst->getOperand(1);

    int32_t arg1_reg_no = arg1->getRegId();
    int32_t arg2_reg_no = arg2->getRegId();
    int32_t result_reg_no = inst->getRegId();

    int32_t reg_a = (arg1_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(arg1) : arg1_reg_no;
    if (arg1_reg_no == -1)
        iloc.load_var(reg_a, arg1, false);

    int32_t reg_b = (arg2_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(arg2) : arg2_reg_no;
    if (arg2_reg_no == -1)
        iloc.load_var(reg_b, arg2, false);

    int32_t reg_res = (result_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(result) : result_reg_no;

    // cmp reg_a, reg_b
    iloc.inst("cmp", PlatformArm64::regName[reg_a], PlatformArm64::regName[reg_b]);
    // cset reg_res, ge
    iloc.inst("cset", PlatformArm64::regName[reg_res], "ge");

    // 总是将结果写回内存，确保不会丢失
    iloc.store_var(reg_res, result, ARM64_TMP_REG_NO, false);

    simpleRegisterAllocator.freeInt(arg1);
    simpleRegisterAllocator.freeInt(arg2);
    if (result_reg_no == -1) {
        simpleRegisterAllocator.freeInt(reg_res);
    }
}

/// @brief 等于指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_eq_int32(Instruction * inst)
{
    Value * result = inst;
    Value * arg1 = inst->getOperand(0);
    Value * arg2 = inst->getOperand(1);

    int32_t arg1_reg_no = arg1->getRegId();
    int32_t arg2_reg_no = arg2->getRegId();
    int32_t result_reg_no = inst->getRegId();

    int32_t reg_a = (arg1_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(arg1) : arg1_reg_no;
    if (arg1_reg_no == -1)
        iloc.load_var(reg_a, arg1, false);

    int32_t reg_b = (arg2_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(arg2) : arg2_reg_no;
    if (arg2_reg_no == -1)
        iloc.load_var(reg_b, arg2, false);

    int32_t reg_res = (result_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(result) : result_reg_no;

    // cmp reg_a, reg_b
    iloc.inst("cmp", PlatformArm64::regName[reg_a], PlatformArm64::regName[reg_b]);
    // cset reg_res, eq
    iloc.inst("cset", PlatformArm64::regName[reg_res], "eq");

    // 总是将结果写回内存，确保不会丢失
    iloc.store_var(reg_res, result, ARM64_TMP_REG_NO, false);

    simpleRegisterAllocator.freeInt(arg1);
    simpleRegisterAllocator.freeInt(arg2);
    if (result_reg_no == -1) {
        simpleRegisterAllocator.freeInt(reg_res);
    }
}

/// @brief 不等于指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_ne_int32(Instruction * inst)
{
    Value * result = inst;
    Value * arg1 = inst->getOperand(0);
    Value * arg2 = inst->getOperand(1);

    int32_t arg1_reg_no = arg1->getRegId();
    int32_t arg2_reg_no = arg2->getRegId();
    int32_t result_reg_no = inst->getRegId();

    int32_t reg_a = (arg1_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(arg1) : arg1_reg_no;
    if (arg1_reg_no == -1)
        iloc.load_var(reg_a, arg1, false);

    int32_t reg_b = (arg2_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(arg2) : arg2_reg_no;
    if (arg2_reg_no == -1)
        iloc.load_var(reg_b, arg2, false);

    int32_t reg_res = (result_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(result) : result_reg_no;

    // cmp reg_a, reg_b
    iloc.inst("cmp", PlatformArm64::regName[reg_a], PlatformArm64::regName[reg_b]);
    // cset reg_res, ne  // 不等时为1，等于时为0
    iloc.inst("cset", PlatformArm64::regName[reg_res], "ne");

    // 总是将结果写回内存，确保不会丢失
    iloc.store_var(reg_res, result, ARM64_TMP_REG_NO, false);

    simpleRegisterAllocator.freeInt(arg1);
    simpleRegisterAllocator.freeInt(arg2);
    if (result_reg_no == -1) {
        simpleRegisterAllocator.freeInt(reg_res);
    }
}

/// @brief 逻辑非指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_not_int32(Instruction * inst)
{
    Value * result = inst;
    Value * arg = inst->getOperand(0);

    int32_t arg_reg_no = arg->getRegId();
    int32_t result_reg_no = inst->getRegId();

    int32_t reg_a = (arg_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(arg) : arg_reg_no;
    if (arg_reg_no == -1)
        iloc.load_var(reg_a, arg, false);

    int32_t reg_res = (result_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(result) : result_reg_no;

    // cmp reg_a, wzr/xzr
    iloc.inst("cmp", PlatformArm64::regName[reg_a], PlatformArm64::getZeroRegName(PlatformArm64::regName[reg_a]));
    // cset reg_res, eq   // 逻辑非: 如果为0则为1，否则为0
    iloc.inst("cset", PlatformArm64::regName[reg_res], "eq");

    // 总是将结果写回内存，确保不会丢失
    iloc.store_var(reg_res, result, ARM64_TMP_REG_NO, false);

    simpleRegisterAllocator.freeInt(arg);
    if (result_reg_no == -1) {
        simpleRegisterAllocator.freeInt(reg_res);
    }
}

/// @brief 逻辑与指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_and_int32(Instruction * inst)
{
    Value * result = inst;
    Value * arg1 = inst->getOperand(0);
    Value * arg2 = inst->getOperand(1);

    // 检查操作数类型
    Type * arg1Type = arg1->getType();
    Type * arg2Type = arg2->getType();

    bool arg1_is_float = arg1Type ? arg1Type->isFloatType() : false;
    bool arg2_is_float = arg2Type ? arg2Type->isFloatType() : false;

    int32_t arg1_reg_no = arg1->getRegId();
    int32_t arg2_reg_no = arg2->getRegId();
    int32_t result_reg_no = inst->getRegId();

    int32_t reg_a = (arg1_reg_no == -1) ? simpleRegisterAllocator.Allocate(arg1_is_float, arg1) : arg1_reg_no;
    if (arg1_reg_no == -1)
        iloc.load_var(reg_a, arg1, arg1_is_float);

    int32_t reg_b = (arg2_reg_no == -1) ? simpleRegisterAllocator.Allocate(arg2_is_float, arg2) : arg2_reg_no;
    if (arg2_reg_no == -1)
        iloc.load_var(reg_b, arg2, arg2_is_float);

    int32_t reg_res = (result_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(result) : result_reg_no;

    // 检查第一个操作数是否为非零
    int32_t temp1 = simpleRegisterAllocator.AllocateInt();
    if (arg1_is_float) {
        // 浮点数与0.0比较
        iloc.inst("fcmp", PlatformArm64::regNameS[reg_a], "#0.0");
    } else {
        // 整数与0比较
        iloc.inst("cmp", PlatformArm64::regName[reg_a], PlatformArm64::getZeroRegName(PlatformArm64::regName[reg_a]));
    }
    iloc.inst("cset", PlatformArm64::regName[temp1], "ne");

    // 检查第二个操作数是否为非零
    int32_t temp2 = simpleRegisterAllocator.AllocateInt();
    if (arg2_is_float) {
        // 浮点数与0.0比较
        iloc.inst("fcmp", PlatformArm64::regNameS[reg_b], "#0.0");
    } else {
        // 整数与0比较
        iloc.inst("cmp", PlatformArm64::regName[reg_b], PlatformArm64::getZeroRegName(PlatformArm64::regName[reg_b]));
    }
    iloc.inst("cset", PlatformArm64::regName[temp2], "ne");

    // 逻辑与：两个都非零才为真
    iloc.inst("and", PlatformArm64::regName[reg_res], PlatformArm64::regName[temp1], PlatformArm64::regName[temp2]);

    // 总是将结果写回内存，确保不会丢失
    iloc.store_var(reg_res, result, ARM64_TMP_REG_NO, false);

    simpleRegisterAllocator.free(arg1, arg1_is_float);
    simpleRegisterAllocator.free(arg2, arg2_is_float);
    simpleRegisterAllocator.freeInt(temp1);
    simpleRegisterAllocator.freeInt(temp2);
    if (result_reg_no == -1) {
        simpleRegisterAllocator.freeInt(reg_res);
    }
}

/// @brief 逻辑或指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_or_int32(Instruction * inst)
{
    Value * result = inst;
    Value * arg1 = inst->getOperand(0);
    Value * arg2 = inst->getOperand(1);

    // 检查操作数类型
    Type * arg1Type = arg1->getType();
    Type * arg2Type = arg2->getType();

    bool arg1_is_float = arg1Type ? arg1Type->isFloatType() : false;
    bool arg2_is_float = arg2Type ? arg2Type->isFloatType() : false;

    int32_t arg1_reg_no = arg1->getRegId();
    int32_t arg2_reg_no = arg2->getRegId();
    int32_t result_reg_no = inst->getRegId();

    int32_t reg_a = (arg1_reg_no == -1) ? simpleRegisterAllocator.Allocate(arg1_is_float, arg1) : arg1_reg_no;
    if (arg1_reg_no == -1)
        iloc.load_var(reg_a, arg1, arg1_is_float);

    int32_t reg_b = (arg2_reg_no == -1) ? simpleRegisterAllocator.Allocate(arg2_is_float, arg2) : arg2_reg_no;
    if (arg2_reg_no == -1)
        iloc.load_var(reg_b, arg2, arg2_is_float);

    int32_t reg_res = (result_reg_no == -1) ? simpleRegisterAllocator.AllocateInt(result) : result_reg_no;

    // 检查第一个操作数是否为非零
    int32_t temp1 = simpleRegisterAllocator.AllocateInt();
    if (arg1_is_float) {
        // 浮点数与0.0比较
        iloc.inst("fcmp", PlatformArm64::regNameS[reg_a], "#0.0");
    } else {
        // 整数与0比较
        iloc.inst("cmp", PlatformArm64::regName[reg_a], PlatformArm64::getZeroRegName(PlatformArm64::regName[reg_a]));
    }
    iloc.inst("cset", PlatformArm64::regName[temp1], "ne");

    // 检查第二个操作数是否为非零
    int32_t temp2 = simpleRegisterAllocator.AllocateInt();
    if (arg2_is_float) {
        // 浮点数与0.0比较
        iloc.inst("fcmp", PlatformArm64::regNameS[reg_b], "#0.0");
    } else {
        // 整数与0比较
        iloc.inst("cmp", PlatformArm64::regName[reg_b], PlatformArm64::getZeroRegName(PlatformArm64::regName[reg_b]));
    }
    iloc.inst("cset", PlatformArm64::regName[temp2], "ne");

    // 逻辑或：任意一个非零就为真
    iloc.inst("orr", PlatformArm64::regName[reg_res], PlatformArm64::regName[temp1], PlatformArm64::regName[temp2]);

    // 总是将结果写回内存，确保不会丢失
    iloc.store_var(reg_res, result, ARM64_TMP_REG_NO, false);

    simpleRegisterAllocator.free(arg1, arg1_is_float);
    simpleRegisterAllocator.free(arg2, arg2_is_float);
    simpleRegisterAllocator.freeInt(temp1);
    simpleRegisterAllocator.freeInt(temp2);
    if (result_reg_no == -1) {
        simpleRegisterAllocator.freeInt(reg_res);
    }
}

void InstSelectorArm64::translate_call(Instruction * inst)
{
    int totalOperands = inst->getOperandsNum();
    Value * retVal = nullptr;
    int argCount = 0;
    if (inst->hasResultValue()) {
        // 有返回值，最后一个是返回值
        if (totalOperands > 0) {
            retVal = inst->getOperand(totalOperands - 1);
            argCount = totalOperands - 1;
        }
    } else {
        // 无返回值，所有都是参数
        argCount = totalOperands;
    }

    // 获取当前所有活跃的寄存器（在simpleRegisterAllocator中记录的）
    std::vector<int> regsToSave;
    for (int i = 0; i < PlatformArm64::maxUsableRegNum; i++) {
        if (simpleRegisterAllocator.isRegisterUsed(i) && i > 7) { // 只保存大于x7的寄存器
            regsToSave.push_back(i);
        }
    }

    if (simpleRegisterAllocator.isRegisterUsed(7)) {
        iloc.inst("str", "x7", "[sp, #-16]!");
    }

    // 在函数调用前保存所有活跃的寄存器
    int stackSize = simpleRegisterAllocator.saveActiveRegisters(iloc);

    // 参数传递逻辑保持不变
    for (int i = argCount - 1; i >= 0 && i < 8; --i) {
        Value * arg = inst->getOperand(i);
        if (!arg) {
            minic_log(LOG_ERROR, "Null argument at index %d", i);
            continue;
        }

        // Type * argType = arg->getType();
        bool is_float = false;
        // if (argType) {
        //     is_float = argType->isFloatType();
        // } else {
        //     minic_log(LOG_WARNING, "Argument %d has no type, assuming integer", i);
        // }

        int reg = arg->getRegId();

        if (reg == -1 || reg != i) {
            int srcReg = reg;
            if (reg == -1) {
                srcReg = simpleRegisterAllocator.Allocate(is_float);
                iloc.load_var(srcReg, arg, is_float);
            }

            if (is_float) {
                iloc.inst("fmov", PlatformArm64::regNameS[i], PlatformArm64::regNameS[srcReg]);
            } else {
                iloc.inst("mov", PlatformArm64::regName[i], PlatformArm64::regName[srcReg]);
            }

            if (reg == -1)
                simpleRegisterAllocator.free(srcReg, is_float);
        }
    }

    // 调用函数，函数名通过inst->getName()
    iloc.inst("bl", inst->getName());

    // 恢复所有保存的寄存器
    simpleRegisterAllocator.restoreActiveRegisters(iloc, stackSize);

    if (simpleRegisterAllocator.isRegisterUsed(7)) {
        iloc.inst("ldr", "x7", "[sp], #16");
    }

    // 保存返回值逻辑保持不变
    if (retVal) {
        Type * retType = retVal->getType();
        bool is_float_ret = false;
        if (retType) {
            is_float_ret = retType->isFloatType();
        } else {
            minic_log(LOG_WARNING, "Return value has no type, assuming integer");
        }
        iloc.store_var(0, retVal, ARM64_TMP_REG_NO, is_float_ret);
    }
}

void InstSelectorArm64::translate_arg(Instruction * inst)
{
    // Value * src = inst->getOperand(0);
    // std::string argReg = "x" + std::to_string(realArgCount); // x0 ~ x7

    // if (realArgCount < 8) {
    //     // 前8个参数用寄存器传递
    //     if (auto gv = dynamic_cast<GlobalVariable *>(src)) {
    //         iloc.inst("ldr", "x9", "=" + gv->getName());
    //         iloc.inst("ldr", argReg, "[x9]");
    //     } else if (auto imm = dynamic_cast<Constant *>(src)) {
    //         iloc.inst("mov", argReg, "#" + std::to_string(imm->getVal()));
    //     } else {
    //         int32_t regId = src->getRegId();
    //         if (regId == -1) {
    //             regId = simpleRegisterAllocator.Allocate();
    //             iloc.load_var(regId, src);
    //         }
    //         iloc.inst("mov", argReg, PlatformArm64::regName[regId]);
    //     }
    // } else {
    //     // 超过8个参数，栈上传参，这里简单实现可以报错或放到 sp 偏移
    //     minic_log(LOG_ERROR, "超过8个参数不支持！");
    // }

    // realArgCount++;
}

/// @brief 单目运算符翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_neg_int32(Instruction * inst)
{
    Value * result = inst;
    Value * arg = inst->getOperand(0);

    int32_t arg_reg_no = arg->getRegId();
    int32_t result_reg_no = result->getRegId();

    int32_t load_arg_reg_no;
    if (arg_reg_no == -1) {
        load_arg_reg_no = simpleRegisterAllocator.AllocateInt(arg);
        iloc.load_var(load_arg_reg_no, arg, false);
    } else {
        load_arg_reg_no = arg_reg_no;
    }

    int32_t dest_reg_no;
    if (result_reg_no == -1) {
        dest_reg_no = simpleRegisterAllocator.AllocateInt(result);
    } else {
        dest_reg_no = result_reg_no;
    }

    // 生成ARM64单目运算指令：NEG dest, src
    iloc.inst("neg", PlatformArm64::regName[dest_reg_no], PlatformArm64::regName[load_arg_reg_no]);

    // 总是将结果写回内存，确保不会丢失
    iloc.store_var(dest_reg_no, result, ARM64_TMP_REG_NO, false);

    simpleRegisterAllocator.freeInt(arg);
    if (result_reg_no == -1) {
        simpleRegisterAllocator.freeInt(dest_reg_no);
    }
}

/// @brief 整数取正指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_unary_plus_int32(Instruction * inst)
{
    Value * result = inst;
    Value * arg = inst->getOperand(0);

    int32_t arg_reg_no = arg->getRegId();
    int32_t result_reg_no = result->getRegId();

    int32_t load_arg_reg_no;
    if (arg_reg_no == -1) {
        load_arg_reg_no = simpleRegisterAllocator.AllocateInt(arg);
        iloc.load_var(load_arg_reg_no, arg, false);
    } else {
        load_arg_reg_no = arg_reg_no;
    }

    int32_t dest_reg_no;
    if (result_reg_no == -1) {
        dest_reg_no = simpleRegisterAllocator.AllocateInt(result);
    } else {
        dest_reg_no = result_reg_no;
    }

    // For unary plus, we just need to copy the value
    iloc.inst("mov", PlatformArm64::regName[dest_reg_no], PlatformArm64::regName[load_arg_reg_no]);

    // 总是将结果写回内存，确保不会丢失
    iloc.store_var(dest_reg_no, result, ARM64_TMP_REG_NO, false);

    simpleRegisterAllocator.freeInt(arg);
    if (result_reg_no == -1) {
        simpleRegisterAllocator.freeInt(dest_reg_no);
    }
}

/// @brief branch条件跳转指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_branch(Instruction * inst)
{
    // 假定操作数0为条件，1为真分支label，2为假分支label
    Value * cond = inst->getOperand(0);
    Value * trueLabelVal = inst->getOperand(1);
    Value * falseLabelVal = inst->getOperand(2);

    Type * condType = cond->getType();
    bool is_float = condType && condType->isFloatType();

    int32_t cond_reg_no = cond->getRegId();
    if (cond_reg_no == -1) {
        cond_reg_no = simpleRegisterAllocator.Allocate(is_float, cond);
        iloc.load_var(cond_reg_no, cond, is_float);
    }

    if (is_float) {
        // 浮点型条件：fcmp cond_reg_no, #0.0
        iloc.inst("fcmp", PlatformArm64::regNameS[cond_reg_no], "#0.0");
        // 真分支跳转
        iloc.inst("b.ne", trueLabelVal->getName());
        // 假分支跳转
        iloc.inst("b", falseLabelVal->getName());
    } else {
        // 整型条件：cmp cond_reg_no, wzr/xzr
        iloc.inst("cmp",
                  PlatformArm64::regName[cond_reg_no],
                  PlatformArm64::getZeroRegName(PlatformArm64::regName[cond_reg_no]));
        iloc.inst("b.ne", trueLabelVal->getName());
        iloc.inst("b", falseLabelVal->getName());
    }

    simpleRegisterAllocator.free(cond_reg_no, is_float);
}

void InstSelectorArm64::translate_cast(Instruction * inst)
{
    Value * src = inst->getOperand(0);
    Type * srcType = src->getType();
    Type * dstType = inst->getType();

    bool srcIsFloat = srcType->isFloatType();
    bool dstIsFloat = dstType->isFloatType();

    int32_t srcRegId = simpleRegisterAllocator.Allocate(srcIsFloat);
    int32_t dstRegId = simpleRegisterAllocator.Allocate(dstIsFloat);

    // 加载源操作数
    iloc.load_var(srcRegId, src, srcIsFloat);

    // 类型转换
    if (srcIsFloat && !dstIsFloat) {
        // float -> int: 使用w寄存器
        std::string srcRegName = "s" + std::to_string(srcRegId);
        std::string dstRegName = "w" + std::to_string(dstRegId);
        iloc.inst("fcvtzs", dstRegName, srcRegName);

        // 存储时指定是32位整数
        iloc.store_var(dstRegId, inst, ARM64_TMP_REG_NO, false);
    } else if (!srcIsFloat && dstIsFloat) {
        // int -> float
        std::string srcRegName = "w" + std::to_string(srcRegId);
        std::string dstRegName = "s" + std::to_string(dstRegId);
        iloc.inst("scvtf", dstRegName, srcRegName);

        // 存储浮点数
        iloc.store_var(dstRegId, inst, ARM64_TMP_REG_NO, true);
    } else {
        // 其他转换
        if (srcIsFloat && dstIsFloat) {
            iloc.inst("fmov", PlatformArm64::regNameS[dstRegId], PlatformArm64::regNameS[srcRegId]);
        } else {
            iloc.mov_reg(dstRegId, srcRegId);
        }
        iloc.store_var(dstRegId, inst, ARM64_TMP_REG_NO, dstIsFloat);
    }

    simpleRegisterAllocator.free(srcRegId, srcIsFloat);
    simpleRegisterAllocator.free(dstRegId, dstIsFloat);
}

/// @brief 数组访问指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_array_access(Instruction * inst)
{
    // 1. 尝试将inst转换为GEP指令
    auto gep = dynamic_cast<GetElementPtrInstruction *>(inst);
    if (!gep) {
        // 不是GEP指令，直接返回
        return;
    }

    // 2. 获取GEP的结果（通常是RegVariable*）
    Value * gep_result = gep->getResult();
    auto regvar = dynamic_cast<RegVariable *>(gep_result);
    // 若不是RegVariable，也可以继续用Value接口

    // 3. 获取GEP的基址和所有索引
    Value * base = gep->getPointer();
    std::vector<Value *> indices = gep->getIndices();

    // 4. 分配寄存器给GEP结果 - 数组访问通常是地址，使用整型寄存器
    int32_t gep_reg = -1;
    if (regvar) {
        gep_reg = regvar->getRegId();
        if (gep_reg == -1) {
            gep_reg = simpleRegisterAllocator.AllocateInt(regvar);
            regvar->setLoadRegId(gep_reg);
        }
    } else {
        gep_reg = simpleRegisterAllocator.AllocateInt(gep_result);
        gep_result->setLoadRegId(gep_reg);
    }

    // 5. 计算base寄存器
    int32_t base_reg = base->getRegId();
    if (base_reg == -1) {
        base_reg = simpleRegisterAllocator.AllocateInt(base);

        // 检查是否是数组类型，区分处理方式
        if (base->getType()->isPointerType()) {
            const PointerType * ptrType = dynamic_cast<const PointerType *>(base->getType());
            if (ptrType && ptrType->isArray()) {
                // 数组类型，直接获取地址
                iloc.lea_var(base_reg, base);
            } else {
                // 非数组指针，需要先ldr解引用
                // 先获取指针的地址
                iloc.lea_var(base_reg, base);
                // 然后从该地址加载真正的数组基地址
                iloc.inst("ldr", PlatformArm64::regName[base_reg], "[" + PlatformArm64::regName[base_reg] + "]");
            }
        } else {
            // 非指针类型，使用原来的逻辑
            iloc.lea_var(base_reg, base);
        }
    }

    // 6. 处理多维数组索引
    if (indices.size() > 1) {
        // 多维数组：需要计算复杂的地址偏移
        int32_t offset_reg = -1;
        int32_t temp_reg = -1;

        // 分配临时寄存器用于计算偏移 - 使用整型寄存器
        offset_reg = simpleRegisterAllocator.AllocateInt();
        temp_reg = simpleRegisterAllocator.AllocateInt();

        // 初始化偏移为0
        iloc.inst("mov", PlatformArm64::regName[offset_reg], "xzr");

        // 获取数组类型信息
        PointerType * arrayType = dynamic_cast<PointerType *>(base->getType());
        PointerType * currentType = arrayType;
        while (currentType && !currentType->isArray() && currentType->getPointeeType()) {
            currentType = dynamic_cast<PointerType *>(const_cast<Type *>(currentType->getPointeeType()));
        }
        if (!currentType || !currentType->isArray()) {
            minic_log(LOG_ERROR, "Invalid array type for GEP instruction");
            return;
        }

        // 判断是否需要跳过第一个索引
        size_t startIndex = (arrayType == currentType) ? 1 : 0;

        // 获取数组维度信息用于行主序计算
        std::vector<int> dimensions = gep->getArrayDimensions();

        for (size_t i = startIndex; i < indices.size(); i++) {
            Value * index = indices[i];
            if (!index)
                continue;

            // 加载索引值到寄存器 - 索引通常是整数
            int32_t index_reg = index->getRegId();
            if (index_reg == -1) {
                index_reg = simpleRegisterAllocator.AllocateInt(index);
                iloc.load_var(index_reg, index, false);
            }

            // 计算当前维度的步长（行主序）
            int stride = 1;
            if (!startIndex) {
                if (i - startIndex < dimensions.size()) {
                    // 计算当前维度的步长：stride[i] = dimensions[i+1] * dimensions[i+2] * ... * elementSize
                    for (size_t j = i - startIndex + 1; j <= dimensions.size(); j++) {
                        stride *= dimensions[j - 1];
                    }
                }
            } else {
                if (i - startIndex < dimensions.size()) {
                    // 计算当前维度的步长：stride[i] = dimensions[i+1] * dimensions[i+2] * ... * elementSize
                    for (size_t j = i - startIndex + 1; j < dimensions.size(); j++) {
                        stride *= dimensions[j];
                    }
                }
            }

            // 获取元素大小
            // int elementSize = 8; // 假设每个元素8字节
            // if (currentType->getElementType()) {
            //     elementSize = currentType->getElementType()->getSize();
            // }
            stride *= 8;

            // 计算当前维度的偏移：index * stride
            if (stride == 8) {
                // 步长为8，使用lsl #3
                iloc.inst("lsl", PlatformArm64::regName[temp_reg], PlatformArm64::regName[index_reg], "#3");
            } else if (stride == 4) {
                // 步长为4，使用lsl #2
                iloc.inst("lsl", PlatformArm64::regName[temp_reg], PlatformArm64::regName[index_reg], "#2");
            } else if (stride == 2) {
                // 步长为2，使用lsl #1
                iloc.inst("lsl", PlatformArm64::regName[temp_reg], PlatformArm64::regName[index_reg], "#1");
            } else if (stride == 1) {
                // 步长为1，直接复制
                iloc.inst("mov", PlatformArm64::regName[temp_reg], PlatformArm64::regName[index_reg]);
            } else {
                // 其他步长，使用乘法 - 修复：使用load_imm而不是直接mov
                iloc.load_imm(temp_reg, stride);
                iloc.inst("mul",
                          PlatformArm64::regName[temp_reg],
                          PlatformArm64::regName[index_reg],
                          PlatformArm64::regName[temp_reg]);
            }

            // 累加到总偏移
            iloc.inst("add",
                      PlatformArm64::regName[offset_reg],
                      PlatformArm64::regName[offset_reg],
                      PlatformArm64::regName[temp_reg]);

            // 更新当前类型为下一层
            if (currentType->getElementType() && currentType->getElementType()->isPointerType()) {
                currentType = dynamic_cast<PointerType *>(const_cast<Type *>(currentType->getElementType()));
            }

            // 释放索引寄存器
            if (index_reg != index->getRegId()) {
                simpleRegisterAllocator.freeInt(index_reg);
            }
        }

        // 计算最终地址：gep_reg = base_reg + offset_reg
        iloc.inst("add",
                  PlatformArm64::regName[gep_reg],
                  PlatformArm64::regName[base_reg],
                  PlatformArm64::regName[offset_reg]);

        // 释放临时寄存器
        simpleRegisterAllocator.freeInt(offset_reg);
        simpleRegisterAllocator.freeInt(temp_reg);
    } else if (indices.size() == 1) {
        // 单维数组：简单的索引计算
        Value * index = indices[0];
        if (index) {
            int32_t index_reg = index->getRegId();
            if (index_reg == -1) {
                index_reg = simpleRegisterAllocator.AllocateInt(index);
                iloc.load_var(index_reg, index, false);
            }

            // 计算偏移：index * 8
            iloc.inst("lsl", PlatformArm64::regName[index_reg], PlatformArm64::regName[index_reg], "#3");

            // 计算最终地址：gep_reg = base_reg + index_reg
            iloc.inst("add",
                      PlatformArm64::regName[gep_reg],
                      PlatformArm64::regName[base_reg],
                      PlatformArm64::regName[index_reg]);

            // 释放索引寄存器
            if (index_reg != index->getRegId()) {
                simpleRegisterAllocator.freeInt(index_reg);
            }
        } else {
            // 没有索引，直接复制基地址
            iloc.inst("mov", PlatformArm64::regName[gep_reg], PlatformArm64::regName[base_reg]);
        }
    } else {
        // 没有索引，直接复制基地址
        iloc.inst("mov", PlatformArm64::regName[gep_reg], PlatformArm64::regName[base_reg]);
    }

    // 7. 释放base寄存器
    if (base_reg != base->getRegId()) {
        simpleRegisterAllocator.freeInt(base_reg);
    }
    // gep_reg不释放，后续还会用
}

/// @brief 存储指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_store(Instruction * inst)
{
    Value * value = inst->getOperand(1); // 要存储的值
    Value * addr = inst->getOperand(0);  // 目标地址

    bool is_float = value->getType()->isFloatType();

    int32_t value_reg_no = -1;
    Instanceof(val_inst, Instruction *, value);
    if (val_inst) {
        value_reg_no = val_inst->getLoadRegId();
    } else {
        value_reg_no = value->getLoadRegId();
    }
    if (value_reg_no == -1) {
        value_reg_no = value->getRegId();
    }

    int32_t addr_reg_no = -1;
    Instanceof(addr_inst, Instruction *, addr);
    if (addr_inst) {
        addr_reg_no = addr_inst->getLoadRegId();
    } else {
        addr_reg_no = addr->getLoadRegId();
    }
    if (addr_reg_no == -1) {
        addr_reg_no = addr->getRegId();
    }

    int32_t temp_reg_no = -1;
    if (addr_reg_no == -1) {
        temp_reg_no = simpleRegisterAllocator.AllocateInt(); // 地址总是整型
        iloc.load_var(temp_reg_no, addr, false);
        addr_reg_no = temp_reg_no;
    }
    if (value_reg_no == -1) {
        temp_reg_no = simpleRegisterAllocator.Allocate(is_float);
        iloc.load_var(temp_reg_no, value, is_float);
        value_reg_no = temp_reg_no;
    }

    if (is_float) {
        iloc.inst("str", PlatformArm64::regNameS[value_reg_no], "[" + PlatformArm64::regName[addr_reg_no] + "]");
    } else {
        iloc.inst("str", PlatformArm64::regName[value_reg_no], "[" + PlatformArm64::regName[addr_reg_no] + "]");
    }

    if (temp_reg_no != -1)
        simpleRegisterAllocator.free(temp_reg_no, is_float);
}

/// @brief 加载指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_load(Instruction * inst)
{
    Value * result = inst->getOperand(0);
    Value * addr = inst->getOperand(1);

    bool is_float = result->getType()->isFloatType();

    int32_t result_reg_no = result->getRegId();
    if (result_reg_no == -1)
        result_reg_no = simpleRegisterAllocator.Allocate(is_float, result);

    int32_t addr_reg_no = -1;
    Instanceof(addr_inst, Instruction *, addr);
    if (addr_inst) {
        addr_reg_no = addr_inst->getLoadRegId();
    } else {
        addr_reg_no = addr->getLoadRegId();
    }
    if (addr_reg_no == -1) {
        addr_reg_no = addr->getRegId();
    }

    int32_t temp_reg_no = -1;
    if (addr_reg_no == -1) {
        temp_reg_no = simpleRegisterAllocator.AllocateInt(); // 地址总是整型
        iloc.load_var(temp_reg_no, addr, false);
        addr_reg_no = temp_reg_no;
    }

    if (is_float) {
        iloc.inst("ldr", PlatformArm64::regNameS[result_reg_no], "[" + PlatformArm64::regName[addr_reg_no] + "]");
    } else {
        iloc.inst("ldr", PlatformArm64::regName[result_reg_no], "[" + PlatformArm64::regName[addr_reg_no] + "]");
    }

    result->setLoadRegId(result_reg_no);
    if (temp_reg_no != -1)
        simpleRegisterAllocator.freeInt(temp_reg_no);
}

/// @brief ZEROSET指令翻译成ARM64汇编
/// @param inst IR指令
void InstSelectorArm64::translate_zeroset(Instruction * inst)
{
    // ZEROSET指令用于数组零初始化
    // 操作数0是数组的基地址指针
    Value * arrayPtr = inst->getOperand(0);

    // 获取数组基地址 - 使用整型寄存器
    int32_t array_reg_no = arrayPtr->getRegId();
    if (array_reg_no == -1) {
        array_reg_no = simpleRegisterAllocator.AllocateInt();
        iloc.lea_var(array_reg_no, arrayPtr);
    }

    // 使用wzr/xzr寄存器（恒为0），不需要分配临时寄存器
    std::string zero_reg = PlatformArm64::getZeroRegName(PlatformArm64::regName[array_reg_no]);

    // 计算数组大小
    int32_t array_size = 0;
    int32_t element_count = 0;
    if (arrayPtr->getType()->isPointerType()) {
        // 获取数组类型信息
        Type * elementType = arrayPtr->getType();
        if (elementType->isPointerType()) {
            // 计算数组总大小（字节数）
            array_size = elementType->getSize();
            // 假设每个元素是8字节，计算元素个数
            element_count = array_size / 8;
        }
    }

    // 对于固定大小的数组，使用多个连续的str指令而不是循环
    // 这样可以避免循环开销，提高性能
    for (int i = 0; i < element_count; i++) {
        int32_t offset = i * 8; // 每个元素8字节
        if (offset == 0) {
            // 第一个元素，直接使用基地址
            iloc.inst("str", zero_reg, "[" + PlatformArm64::regName[array_reg_no] + "]");
        } else if (offset < 32768) {
            // 后续元素，使用基地址+偏移（小偏移量）
            iloc.inst("str",
                      zero_reg,
                      "[" + PlatformArm64::regName[array_reg_no] + ", #" + std::to_string(offset) + "]");
        } else {
            // 大偏移量，需要先计算地址
            int tmp_reg = simpleRegisterAllocator.AllocateInt();
            iloc.load_imm(tmp_reg, offset);
            iloc.inst("add",
                      PlatformArm64::regName[tmp_reg],
                      PlatformArm64::regName[array_reg_no],
                      PlatformArm64::regName[tmp_reg]);
            iloc.inst("str", zero_reg, "[" + PlatformArm64::regName[tmp_reg] + "]");
            simpleRegisterAllocator.freeInt(tmp_reg);
        }
    }
    // 释放数组寄存器（如果之前分配了的话）
    if (array_reg_no != arrayPtr->getRegId()) {
        simpleRegisterAllocator.freeInt(array_reg_no);
    }
}
